{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SVD-- \n",
      " U=\n",
      "[[ 1.          0.          0.        ]\n",
      " [ 0.          0.70710678  0.70710678]\n",
      " [ 0.          0.70710678 -0.70710678]]\n",
      " Z=\n",
      "[[2. 0.]\n",
      " [0. 1.]\n",
      " [0. 0.]]\n",
      " V=\n",
      "[[1. 0.]\n",
      " [0. 1.]]\n",
      "**********\n",
      "[[2.         0.        ]\n",
      " [0.         0.70710678]\n",
      " [0.         0.70710678]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "def get_data2():\n",
    "    return np.array([[2, 0],\n",
    "                     [0, 1 / np.sqrt(2)],\n",
    "                     [0, 1 / np.sqrt(2)], ])\n",
    "\n",
    "\n",
    "def get_data():\n",
    "    return np.array([[1, 0, 0, 0, 2],\n",
    "                     [0, 0, 3, 0, 0],\n",
    "                     [0, 0, 0, 0, 0],\n",
    "                     [0, 4, 0, 0, 0]])\n",
    "\n",
    "\n",
    "def get_eigenvalue(A):\n",
    "    return np.linalg.eigvals(A)\n",
    "\n",
    "\n",
    "def get_U(A):\n",
    "    return np.linalg.eig(A.dot(A.T))\n",
    "\n",
    "\n",
    "def get_V(A):\n",
    "    return np.linalg.eig(A.T.dot(A))\n",
    "\n",
    "\n",
    "def SVD():\n",
    "    sigma, V = get_V(A)\n",
    "    sigma, V, length = bubble_sort(sigma, V)\n",
    "    sigma2, U = get_U(A)\n",
    "    sigma, U, _ = bubble_sort(sigma2, U)\n",
    "    S = np.zeros((m, n))\n",
    "    for i in range(length):\n",
    "        S[i][i] = np.sqrt(sigma[i])\n",
    "\n",
    "    # print(S)\n",
    "    # U = np.zeros((m, m))\n",
    "    # print(U.shape)\n",
    "    for i in range(length):\n",
    "        # print((1 / np.sqrt(sigma[i])) * np.dot(A, V[:, i]))\n",
    "        U[:, i] = (1 / np.sqrt(sigma[i])) * np.dot(A, V[:, i])\n",
    "    return U, S, V\n",
    "\n",
    "\n",
    "def bubble_sort(sigma, B):\n",
    "    \"\"\"\n",
    "    对奇异值进行排序\n",
    "    :param sigma:\n",
    "    :param B:\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    length = len(sigma)\n",
    "    for i in range(length - 1):\n",
    "        # i表示比较多少轮\n",
    "        for j in range(length - i - 1):\n",
    "            if sigma[j] < sigma[j + 1]:\n",
    "                sigma[j], sigma[j + 1] = sigma[j + 1], sigma[j]\n",
    "                B[:, [j, j + 1]] = B[:, [j + 1, j]]\n",
    "    temp = 0\n",
    "    for i in range(length):\n",
    "        if sigma[i] > 0:\n",
    "            temp = temp + 1\n",
    "    return sigma, B, temp\n",
    "\n",
    "\n",
    "# 获取数据\n",
    "A = get_data2()\n",
    "m = A.shape[0]\n",
    "n = A.shape[1]\n",
    "k = min(m, n)\n",
    "\n",
    "U, S, V = SVD()\n",
    "temp2 = np.dot(np.dot(U, S), V.T)\n",
    "print(\"SVD-- \\n U=\\n{}\\n Z=\\n{}\\n V=\\n{}\".format(U, S, V))\n",
    "print(\"*\" * 10)\n",
    "print(temp2)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}